/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package deatax.util;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author pson
 */
public class XmlUtil {
    private static HashMap<String, XPathExpression> cache = new HashMap<String, XPathExpression>();
    private static XPath xPath = XPathFactory.newInstance().newXPath();
    
    public static Element loadObject(Object obj) {
        try {
            Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(String.valueOf(obj).getBytes()));
            NodeList node = doc.getElementsByTagName("root");
            for (int i = 0; i < node.getLength(); ++i) {
                if (node.item(i).getNodeType() == Node.ELEMENT_NODE) {
                    Element root = (Element) node.item(i);
                    root.normalize();
                    return root;
                }
            }
            System.err.println("Unable to locate root node");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static Element loadFile(String filename) {
        File file = new File(filename);
        return loadFile(file);
    }

    public static Element loadStream(InputStream is) throws URISyntaxException {

        Document doc = null;
        try {
            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }

        NodeList node = doc.getElementsByTagName("root");
        for (int i = 0; i < node.getLength(); ++i) {
            if (node.item(i).getNodeType() == Node.ELEMENT_NODE) {
                Element root = (Element) node.item(i);
                root.normalize();
                return root;
            }
        }
        System.err.println("Unable to locate root node");
        return null;

    }

    public static Element loadFile(File file) {

        Document doc = null;
        try {
            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }

        NodeList node = doc.getElementsByTagName("root");
        for (int i = 0; i < node.getLength(); ++i) {
            if (node.item(i).getNodeType() == Node.ELEMENT_NODE) {
                Element root = (Element) node.item(i);
                root.normalize();
                return root;
            }
        }
        System.err.println("Unable to locate root node");
        return null;
    }
    
    public static String getValue(Element ele, String path) {
        try {
            if (!cache.containsKey(path)) {
                XPathExpression xpe = xPath.compile(path);
                cache.put(path, xpe);
            }
            //printElement(ele, 0, -1);
            //System.out.println("path: " + path);
            return cache.get(path).evaluate(ele);
            //return xPath.evaluate(path, ele);
        } catch (XPathExpressionException ex) {
            //Logger.getLogger(UTIL.class.getName()).log(Level.SEVERE, null, ex);
        }
        return "";
    }

    public static ArrayList<String> getValues(Element ele, String path) {
        try {
            if (!cache.containsKey(path)) {
                XPathExpression xpe = xPath.compile(path);
                cache.put(path, xpe);
            }
            //printElement(ele, 0, -1);
            //System.out.println("path: " + path);
            NodeList nodes = (NodeList) cache.get(path).evaluate(ele, XPathConstants.NODESET);
            ArrayList<String> list = new ArrayList<String>();
            for (int i = 0; i < nodes.getLength(); ++i) {
                list.add(nodes.item(i).getTextContent());
            }
            return list;
            //return xPath.evaluate(path, ele);
        } catch (XPathExpressionException ex) {
            //Logger.getLogger(UTIL.class.getName()).log(Level.SEVERE, null, ex);
        }
        return new ArrayList<String>();
    }
}
